#include "stdafx.h"
MergeInfo::MergeInfo()
{
	Ready=IsCreated=0;
	TimeArray=NULL;
	PingArray=NULL;
	uiReadyCount=0;
	bWrited=0;
}
MergeInfo::~MergeInfo()
{
	if (IsCreated)
	{	
		delete TimeArray;
		delete PingArray;
	}
}
void MergeInfo::SetReadyCount(uint uiCount)
{
	uiReadyCount=uiCount;
	TimeArray=new time_t[uiCount];
	PingArray=new uint[uiCount];
	for (int i=0; i<uiCount; i++)
	{
		TimeArray[i]=0;
		PingArray[i]=0;
	}
	IsCreated=1;
}
uint MergeInfo::GetPing()
{
	if (Ready)
		return result_ping;
	else
		return 0;
}
time_t MergeInfo::GetTime()
{
	if (Ready)
		return result_time;
	else
		return 0;
}
void MergeInfo::Add(time_t ttTime, uint uiPing)
{
	bWrited=false;
	if (!Ready)
	{
		uint index;
		for (index=0; TimeArray[index]!=0; index++);
		if (index<uiReadyCount)
		{
			TimeArray[index]=ttTime;
			PingArray[index]=uiPing;
			if (index==uiReadyCount-1)
			{
				Ready=true;
				Merge();
			}
		} else
			Merge();
	} else
	{
		delete TimeArray;
		delete PingArray;
		TimeArray=new time_t[uiReadyCount];
		PingArray=new uint[uiReadyCount];
		for (int i=0; i<uiReadyCount; i++)
		{
			TimeArray[i]=0;
			PingArray[i]=0;
		}
		Ready=0;
		Add(ttTime,uiPing);
	}
}
bool MergeInfo::IsReady()
{
	return Ready;
}
void MergeInfo::Merge()
{
	uint last=0;
	for (int i=0; i<uiReadyCount; i++)
		if (TimeArray[i]!=0)
			last++;
		else
			break;
	if (uiReadyCount==0||last==0)
	{
		result_ping=0;
		result_time=0;
		Ready=1;
		return;
	} else
	{
		__int64 sum=0;
		for(int i=0; i<last; i++)
			sum+=TimeArray[i];
		result_time=sum/last;
		sum=0;
		for(int i=0; i<last; i++)
			sum+=PingArray[i];
		result_ping=sum/last;
		Ready=1;
	}
}
//////////////////////////////////////////////////////////////////////////
DataBase::DataBase()
{
	name=0;
	id=0;
}
void DataBase::Create(uint uiId, char *sName,uint MachineCount, uint uiWait)
{
	name= new char[256];
	strcpy(name,sName);
	id=uiId;
	miData.SetReadyCount(MachineCount);
	file=new DTBFile;
	file->Open(sName);
	LastTime=-1;
	uiWaitTime=uiWait;

}
DataBase::~DataBase()
{
	delete name;
	delete file;
}
void DataBase::AddInfo(uint uiId, time_t ttTime, uint Ping)
{
	if (LastTime==-1)
		LastTime=GetTickCount();
	if (uiId==id)
	{
		miData.Add(ttTime,Ping);
		if (miData.IsReady())
			Update(GetTickCount());
	}
}
void DataBase::Update(uint uiTime)
{
	if (miData.IsReady())
	{
		if (!miData.bWrited)
		{
			file->Write(miData.GetTime(),miData.GetPing());
			miData.bWrited=1;
		}
	}else
	{
		if (uiTime-LastTime>uiWaitTime)
		{
			LastTime=GetTickCount();
			miData.Merge();
			file->Write(miData.GetTime(),miData.GetPing());
		}
	}
}
void DataBase::SetWaitTime(uint uiTime)
{
	uiWaitTime=uiTime;
}
//////////////////////////////////////////////////////////////////////////
DBManager::DBManager()
{
	db=0;
	uiCount=0;
	uiLast=0;
}
DBManager::~DBManager()
{
	if (db!=NULL)
		delete[] db;
}
void DBManager::LoadDatabaseListFromFile(char *filename)
{
	MFile list;
	uint uiLen,Count=0;
	list.Open(filename);
	fseek(list.GetFile(),0,S_END);
	uiLen=ftell(list.GetFile());
	fseek(list.GetFile(),0,S_BEGIN);
	while(ftell(list.GetFile())<uiLen)
	{
		Count++;
		list.GoToNextBlock();
	}
	uiCount=Count;
	fseek(list.GetFile(),0,S_BEGIN);
	for (int i=0; i<uiCount; i++)
	{
		uint id;
		char buf[256];
		memset(buf,0,256);
		id=list.GetID();
		list.GetURL(buf);
		AddDatabase(id,buf);
		list.GoToNextBlock();
	}
}
void DBManager::AddDatabase(uint id,char *name)
{
	if (db==NULL)
		db=new DataBase[uiCount];
	db[uiLast].Create(id,name,uiCount,5000);
	uiLast++;

}
void DBManager::Update(uint uiTime)
{
	for (int i=0; i<uiLast; i++)
		db[i].Update(uiTime);
}
void DBManager::TranslateMessage(char *buf, uint uiSize)
{
	uint uiEvent;
	uint uiPos=0;
	memcpy(&uiEvent,buf,sizeof(uiEvent));
	uiPos+=sizeof(uiEvent);
	switch(uiEvent)
	{
	case EVENT_SEND_DATA:
		uint uiIdp,uiPing;
		time_t ttTime;
		memcpy(&ttTime,&buf[uiPos],sizeof(ttTime));
		uiPos+=sizeof(ttTime);
		while (uiPos<uiSize)
		{
			memcpy(&uiIdp,&buf[uiPos],sizeof(uiIdp));
			uiPos+=sizeof(uiIdp);
			memcpy(&uiPing,&buf[uiPos],sizeof(uiPing));
			uiPos+=sizeof(uiPing);
			for (int i=0; i<uiLast; i++)
				db[i].AddInfo(uiIdp,ttTime,uiPing);
		}
		break;
	}

}
uint DBManager::GetDBId(uint uiNum)
{
	return db[uiNum].id; 
}